package tau_sadna.tau_map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.core.graphics.Canvas;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.layer.overlay.Marker;
import org.mapsforge.map.util.MapViewProjection;

import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.util.Log;



public class TauLayer extends org.mapsforge.map.layer.Layer {
	
	// map of vertical offsets multiplier.
	protected static HashMap<String, Double> map = null;
	protected static double defult = 0;
	public static void setOffsetMul(String name, double num){
		if(map == null){
			map = new HashMap<String, Double>();
		}
		
		map.put(name, Double.valueOf(num));
	}
	public static double getOffsetMul(String name){
		if(map == null || !map.containsKey(name)){
			return defult;
		}
		
		return map.get(name).doubleValue();
	}
	
	
	
	public List<LayerItem> items;
	public final String name_he;
	public final String name_en;
	public boolean display;
	
	public String pic_name;
	public Bitmap pic;
	public List<Marker> markers;
	
	protected double vOffsetMul;
	
	MainActivity mainAct;
	MapView mainMapView;
	protected boolean isDislplayed = false;
	protected DisplayChangeListener displayChangeListener;
	
	public TauLayer(String name_en,String name_he,boolean forDisp){
		this.items = new ArrayList<LayerItem>();
		this.display = forDisp;
		this.name_he = name_he;
		this.name_en = name_en;
		this.markers = new ArrayList<Marker>();
		return;
	}
	
	// important: this function needs to be called when the parser finishes populating the field 'items'.
	// this function assumes that there will be no further changes to 'items', so that it can initialize the field
	// 'actualLayer' which is a layer of mapforge's type that can be added/removed
	public void finishedPopulating(MainActivity mainAct) {
		vOffsetMul = getOffsetMul(pic_name); //vertical offset
		
		this.mainAct = mainAct;
		Drawable drawable = null;
		try {
			drawable = mainAct.getResources().getDrawable((Integer) R.drawable.class.getField(pic_name).get(R.drawable.class));
		} catch (Exception e) {
			e.printStackTrace();
		} //TODO to be changed to pic_name
		Bitmap bitmap = AndroidGraphicFactory.convertToBitmap(drawable);
		bitmap.incrementRefCount();
		this.pic = bitmap;
		for (LayerItem li : items) {
			markers.add(markerFromLayer(li));
		}
		Log.i("TauLayer", "This layer has "+items.size()+" items, and it's pic is: "+pic_name);
	}
	
	public void showExtraInfo(MainActivity main, String text, String name, String pic) {
		main.addExtraInfo(new ExtraInfo(main, text, name, pic));
	}
	
	public MLString getName() {
		return new MLString(this.name_en,this.name_he);
	}
	public void addTo(MapView mapView) {
		if (isDislplayed)
			return;   //Mapsforge cannot handle a layer added twice to a map view
		isDislplayed = true;
		this.mainMapView = mapView;
		Editor editor = mainAct.sharedPreferences.edit();
		editor.putString(this.name_en, "shown");
		editor.commit();
		Log.i("TauLayer", "Writing 'shown' to sharedPreferences for layer: "+name_en);
		
		mapView.getLayerManager().getLayers().add(this);
		for (Marker mark : markers) {
			mark.setDisplayModel(this.displayModel);
		}
		if (displayChangeListener != null)
			displayChangeListener.onAdd(this, mapView);
	}
	
	public void removeFrom(MapView mapView) {
		if (!isDislplayed)
			return;
		isDislplayed = false;
		Editor editor = mainAct.sharedPreferences.edit();
		editor.putString(this.name_en, "not shown");
		editor.commit();
		Log.i("TauLayer", "Writing 'not shown' to sharedPreferences for layer: "+name_en);
		mapView.getLayerManager().getLayers().remove(this);
		if (displayChangeListener != null)
			displayChangeListener.onRemove(this, mapView);
	}
	
	private Marker markerFromLayer(LayerItem li) {
		LatLong loc = new LatLong(li.lat, li.lon);
		Marker result = new FatMarker(loc, Utils.rotateBitmap(pic, 0), 0, (int)(vOffsetMul*pic.getHeight()), li.extra_data().getName(), li.getName().getName(), li.extra_data_pic);
		return result;
	}	
	
	@Override
	public boolean onLongPress(LatLong tapLatLong, Point layerXY, Point tapXY) {
		super.onLongPress(tapLatLong, layerXY, tapXY);
		MapViewProjection proj = new MapViewProjection(mainMapView);
		for (Marker mark : markers) {
			Point onScreen = proj.toPixels(mark.getLatLong());
			if (mark.contains(onScreen, tapXY)) {
				FatMarker fat = (FatMarker)mark;
				Log.i("TauLayer", "Adding some text box. Text is: "+fat.extraInfo);
				if (fat.extraInfo == null) {
					MLString noinfo = new MLString("No info available", mainAct.getResources().getString(R.string.ain_meida));
					showExtraInfo(mainAct, noinfo.getName(), fat.name, fat.pic);
				} else {
					showExtraInfo(mainAct, fat.extraInfo, fat.name, fat.pic);
				}
				return true;
			}
		}
		return false;		
	}
	
	@Override
	public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
		super.onTap(tapLatLong, layerXY, tapXY);
		return this.onLongPress(tapLatLong, layerXY, tapXY);
	}
	
	@Override
	public void draw(BoundingBox box, byte zoom, Canvas canvas, Point topLeftPoint) {
		for (Marker mark : markers) {
			mark.draw(box, zoom, canvas, topLeftPoint);
		}
	}

	public void setOnDisplayChangeListener(DisplayChangeListener listener) {
		displayChangeListener = listener;		
	}
}
